package cn.finder.httpcommons.request;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.finder.httpcommons.ApiDictionary;
import cn.finder.httpcommons.ApiObject;
import cn.finder.httpcommons.EnumObject;
import cn.finder.httpcommons.attri.JsonIgnore;
import cn.finder.httpcommons.attri.JsonProperty;
import cn.finder.httpcommons.response.ApiResponse;
import cn.finder.httpcommons.utils.Constants;
import cn.finder.httpcommons.utils.DateUtils;
import cn.finder.httpcommons.utils.FileItem;
import cn.finder.httpcommons.utils.JsonUtils;

public abstract class UploadRequest<T extends ApiResponse> extends BaseRequest<T> implements IUploadRequest<T>{
	/// <summary>
    /// 额外参数
    /// </summary>
    protected Map<String, String> parameters;




    public void addParameter(String key, String value)
    {
        if (this.parameters == null)
        {
            this.parameters = new ApiDictionary();
        }
        this.parameters.put(key, value);

    }


    public abstract String apiName();


    /// <summary>
    /// 默认 获取请求参数   如果参数值为null 那么转成 ''
    /// </summary>
    /// <returns></returns>
    public  Map<String, String> parameters()
    {

    	Class<? extends UploadRequest> c = this.getClass();

		Method[] methods = c.getMethods();
		if (methods != null && methods.length > 0) {

			for (Method method : methods) {

				String methodName = method.getName();

				String propName = "";

				if (methodName.startsWith("get")) {
					JsonIgnore jsonIgnore = method
							.getAnnotation(JsonIgnore.class);
					if (jsonIgnore != null) {
						continue;
					}

					JsonProperty jsonProperty = method
							.getAnnotation(JsonProperty.class);
					if (jsonProperty == null) {

						String nametmp = methodName.substring(3);
						propName = nametmp.substring(0, 1).toLowerCase()
								+ nametmp.substring(1);
					} else {
						if (jsonProperty.name() != null
								&& jsonProperty.name().trim().length() > 0) {
							propName = jsonProperty.name();

						}
					}

					Object propertyValue = null;

					try {
						propertyValue = method.invoke(this);
					} catch (Exception e) {
						e.printStackTrace();
					}
                if (propertyValue == null)
                {
                    propertyValue = "";
                }
                
                
                else if (propertyValue instanceof Date) {
					Date pv = (Date) propertyValue;
					propertyValue = DateUtils.formatDate(pv,
							Constants.DATE_FORMAT);
				} else if (propertyValue instanceof Enum) {
					propertyValue = propertyValue.toString();
				}
                
               
				else if (propertyValue instanceof EnumObject<?>) {
					propertyValue = ((EnumObject<?>) propertyValue)
							.toString();
				} else if (propertyValue instanceof ApiObject) {

                    Map<String, String> p = new HashMap<String, String>();
					parameters(propertyValue, p);
					propertyValue = JsonUtils.objToJsonString(p);

                }
				 else if (propertyValue instanceof List) {
						if (propertyValue == null) {
							propertyValue = "";
						} else {
							List tmpPv = (List) propertyValue;
							List<Map<String, String>> listDict = new ArrayList<Map<String, String>>();
							for (int k = 0; k < tmpPv.size(); k++) {
								Map<String, String> p = new HashMap<String, String>();
								Object itemObj = parameters(tmpPv.get(k), p);
								listDict.add(p);
							}
							propertyValue = JsonUtils.objToJsonString(listDict);

						}
				 }
                
				 else if (propertyValue instanceof FileItem) {
 
	                  //continue;

	                }


                addParameter(propName, propertyValue.toString());

				}

            }
        }

        return parameters;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="obj">对象值</param>
    /// <param name="dict">字段对象</param>
    /// <returns></returns>
		private Map<String, String> parameters(Object obj, Map<String, String> dict) {

			Method[] methods = obj.getClass().getMethods();
			if (methods != null && methods.length > 0) {

				for (Method method : methods) {

					String methodName = method.getName();

					String propName = "";

					if (methodName.startsWith("get")) {
						JsonIgnore jsonIgnore = method
								.getAnnotation(JsonIgnore.class);
						if (jsonIgnore != null) {
							continue;
						}

						JsonProperty jsonProperty = method
								.getAnnotation(JsonProperty.class);
						if (jsonProperty == null) {

							String nametmp = methodName.substring(3);
							propName = nametmp.substring(0, 1).toLowerCase()
									+ nametmp.substring(1);
						} else {
							if (jsonProperty.name() != null
									&& jsonProperty.name().trim().length() > 0) {
								propName = jsonProperty.name();

							}
						}

						Object propertyValue = null;

						try {
							propertyValue = method.invoke(this);
						} catch (Exception e) {
							e.printStackTrace();
						}

						if (propertyValue == null) {
							propertyValue = "";
						}

						
						else if (propertyValue instanceof Date) {
							Date pv = (Date) propertyValue;
							propertyValue = DateUtils.formatDate(pv,
									Constants.DATE_FORMAT);
						}
						
						 else if (propertyValue instanceof Enum)
	                    {
	                        propertyValue = propertyValue.toString();
	                    }

						else if (propertyValue instanceof EnumObject<?>) {
							propertyValue = ((EnumObject<?>) propertyValue)
									.toString();
						} else if (propertyValue instanceof ApiObject) {

							Map<String, String> p = new HashMap<String, String>();

							propertyValue = parameters(propertyValue, p);
						} else if (propertyValue instanceof List) {
							if (propertyValue == null) {
								propertyValue = "";
							} else {

								List tmpPv = (List) propertyValue;
								List<Map<String, String>> listDict = new ArrayList<Map<String, String>>();
								for (int k = 0; k < tmpPv.size(); k++) {
									Map<String, String> p = new HashMap<String, String>();
									Object itemObj = parameters(tmpPv.get(k), p);
									listDict.add(p);
								}
								propertyValue = JsonUtils.objToJsonString(listDict);
							}

						}

						dict.put(propName, propertyValue.toString());

					}
				}
			}

			return parameters;
		}


    public abstract void validate();



    public abstract Map<String, FileItem> fileParameters();
}
